package com.sf.iisp.bind.biz.impl;

import com.sf.iisp.BindingException;
import com.sf.iisp.bind.biz.UnbindingBiz;
import com.sf.iisp.bind.dao.IBindingDao;
import com.sf.iisp.bind.dao.IUnbindingDao;
import com.sf.iisp.bind.domain.*;
import com.sf.iisp.bind.enums.State;
import com.sf.iisp.bind.helper.SDTFHelper;
import com.sf.iisp.common.Constant;
import com.sf.iisp.kafka.adapter.IKafkaProducerPoolDelegate;
import com.sf.iisp.util.DateUtils;
import com.sf.kafka.check.util.JsonUtil;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * Created by qi on 16-7-16.
 */
@Service
@Transactional
public class UnbindingBizImpl implements UnbindingBiz {

    private static final Logger LOGGER = LoggerFactory.getLogger(UnbindingBizImpl.class);

    @Resource
    private IBindingDao bindingDao;

    @Resource
    private IUnbindingDao unbindingDao;

    @Resource
    private RedisTemplate redisTemplate;

    @Qualifier("producer")
    @Resource
    private IKafkaProducerPoolDelegate delegate;

    @Value("${redis.unbinding.key.prefix:unbinding-}")
    private String unBindKeyProfix = "unbinding-";

    @Value("${sdtf.binding.service1.url:58.220.61.26:8078/dataInterface/action.do}")
    private String sdtfBindingUrl1;

    @Value("${sdtf.binding.service2.url:58.220.61.27:8078/dataInterface/action.do}")
    private String sdtfBindingUrl2;

    @Value("${isSendKafka:false}")
    private String isSend;

    @Override
    public Boolean unbind(List<String> phones) throws BindingException {
        return null;
    }

    @Override
    public Boolean unbind(String phone, long time) throws BindingException {
        return null;
    }

    @Override
    public Boolean unbind(String courierPhone, String customerPhone, String virtualNo, String basicTransId, MessageHead head) throws BindingException {

        SDTFHelper accessor = new SDTFHelper(head, basicTransId, new String[]{sdtfBindingUrl1, sdtfBindingUrl2});
        try {
            String response = accessor.accessUnbindSvc(courierPhone, customerPhone, virtualNo);
            LOGGER.info("receive unbind response content = {}", response);
            Map respMessage = JsonUtil.readData(response, Map.class);

            //0 代表成功，1代表失败
            if ("0".equals(respMessage.get("Result"))) {
                LOGGER.info("courierPhone ={},  customerPhone = {}, virtual phone= {} be unbind!", courierPhone, customerPhone, virtualNo);
                return Boolean.TRUE;
            }

            String msg = State.NETWORK.getMsg();
            if (null != respMessage.get("ErrorContent")) {
                msg = (String) respMessage.get("ErrorContent");
            }
            throw new BindingException(State.NETWORK.toString(), msg);
        } catch (BindingException e) {
            LOGGER.error(e.getMessage(), e);
            throw e;
        }

    }

    @Deprecated
    private String unbind(ReceiveBindingInfo receivSgsInfo) {
        UnbindingRecord br = setUnbindRecord(receivSgsInfo);
        return unbind(br);
    }

    private String unbind(UnbindingRecord ubr) {
        ReturnBindingInfo returnInfo = setReturnBindInfo(ubr);

        String courierPhone = ubr.getCourierPhone();
        String customerPhone = ubr.getCustomerPhone();

        LOGGER.info("receive unbind courierPhone = {}, customer phone = {}", courierPhone, customerPhone);
        //已绑定状态
        BindingRecord historyBr = bindingDao.findBindRecordByPhone(State.SUCCESS.toString(), courierPhone, customerPhone);

        //已绑定
        if (historyBr != null) {
            //设置历史记录
            ubr.setOriginTransId(historyBr.getTransId());
            ubr.setVirtualNo(historyBr.getVirtualNo());
            returnInfo.setOriginTransId(historyBr.getTransId());
            returnInfo.setVirtualNo(historyBr.getVirtualNo());
            LOGGER.info("query binding record : courierPhone = {}, customerPhone = {}, virtualNo = {}", historyBr.getCourierPhone(), historyBr.getCustomerPhone(), historyBr.getVirtualNo());

            String vn = historyBr.getVirtualNo();
            //7.供应商解绑定成功后，返回报文，
            returnInfo.setCourierPhone(courierPhone);
            returnInfo.setCustomerPhone(customerPhone);
            returnInfo.setVirtualNo(vn);
            String message = null;
            //状态根据供应商返回结果 设置,然后发送报文
            try {
                if (StringUtils.isBlank(ubr.getReservedTime()) || Constant.RESERVED_TIME.toString().equals(ubr.getReservedTime())) {
                    if (unbind(courierPhone, customerPhone, vn, historyBr.getTransId(), ubr)) {
                        returnInfo.setState(State.SUCCESS.toString());
                        returnInfo.setMsg("解绑成功");
                        ubr.setState(State.SUCCESS.toString());
                        historyBr.setState(State.UNBIND.toString());
                        //return 之后回发送！！！！！
                        message = sendMsg(returnInfo);
                        ubr.setUnbindTime(new Date());

                        unbindingDao.saveOrUpdateUnbindRecord(ubr);
                        bindingDao.updateSaveBindRecord(historyBr);
                    }
                } else {
                    UnbindingRecord historyUbr = unbindingDao.findByStateAndPhones(State.RESERVED.toString(), courierPhone, customerPhone);
                    if (historyUbr != null) {
                        returnInfo.setState(State.EXISTS.toString());
                        returnInfo.setMsg("已经设置预约解绑，无需重复设置");
                        message = sendMsg(returnInfo);
                        //return JsonUtil.writeValueAsString(new ResponseMessage(State.SUCCESS.toString(), "已经设置预约解绑，无需重复设置"));
                    } else {
                        Date reservedDate = DateUtils.str2Date(ubr.getReservedTime(), DateUtils.datetimeFormat);
                        String reserved = DateFormatUtils.format(reservedDate, "yyyyMMddHHmm");
                        String key = unBindKeyProfix + reserved;
                        LOGGER.info("add reserved redis item key = {}, value = {}", key, historyBr);
                        redisTemplate.opsForList().leftPush(key, historyBr);
                        ubr.setState(State.RESERVED.toString());
                        unbindingDao.saveOrUpdateUnbindRecord(ubr);

                        returnInfo.setState(State.RESERVED.toString());
                        returnInfo.setMsg(State.RESERVED.getMsg());
                        //return JsonUtil.writeValueAsString(new ResponseMessage(State.SUCCESS.toString(), "设置预约解绑成功"));
                        //TODO:预约成功不发送报文
                        //

                    }
                }
            } catch (BindingException e) {
                LOGGER.error(e.getMessage(), e);
                returnInfo.setState(e.getErrorCode());
                returnInfo.setMsg(e.getMessage());
                ubr.setState(e.getErrorCode());

                //return 之后回发送！！！！！
                message = sendMsg(returnInfo);
            }

            return message;
        }

        returnInfo.setState(State.FAILURE.toString());
        returnInfo.setMsg("没有找到绑定记录");
        return sendMsg(returnInfo);
    }

    private String sendMsg(ReturnBindingInfo returnInfo) {
        String message = JsonUtil.writeValueAsString(returnInfo);
        LOGGER.info("send unbind message = {}, sent ? = {}", message, isSend);
        //TODO:测试关闭！！！！！！
        if ("true".equals(isSend)) {
            delegate.sendString(message);
        }

        return message;
    }

    @Override
    public String unbind(String json) throws BindingException {
        UnbindingRecord br = JsonUtil.readData(json, UnbindingRecord.class);
        return unbind(br);
    }

    @Override
    public String unbind(BindingRecord bindingRecord) throws BindingException {
        UnbindingRecord ur = setUnbindRecord(bindingRecord);
        return unbind(ur);
    }

    public ReturnBindingInfo setReturnBindInfo(UnbindingRecord br) {
        ReturnBindingInfo rbInfo = new ReturnBindingInfo();
        rbInfo.setCourierPhone(br.getCourierPhone());
        rbInfo.setCustomerPhone(br.getCustomerPhone());
        rbInfo.setMsgType(br.getMsgType());
        rbInfo.setSysCode(br.getSysCode());
        //TODO:define trans id .
        rbInfo.setTransId(UUID.randomUUID().toString());
        rbInfo.setTransTimestamp(DateUtils.date2Str(new Date(), DateUtils.datetimeFormat));
        rbInfo.setExtendField1(br.getExtendField1());
        rbInfo.setExtendField2(br.getExtendField2());
        return rbInfo;
    }


    public UnbindingRecord setUnbindRecord(BindingRecord receivSgsInfo) {
        UnbindingRecord br = new UnbindingRecord();
        br.setCourierPhone(receivSgsInfo.getCourierPhone());
        br.setCustomerPhone(receivSgsInfo.getCustomerPhone());
        br.setMsgType(receivSgsInfo.getMsgType());
        br.setReservedTime(receivSgsInfo.getReservedTime());
        br.setExtendField1(receivSgsInfo.getExtendField1());
        br.setExtendField2(receivSgsInfo.getExtendField2());
        br.setSysCode(receivSgsInfo.getSysCode());
        br.setOriginTransId(receivSgsInfo.getTransId());
        br.setTransId(receivSgsInfo.getTransId());
        br.setTransTimestamp(receivSgsInfo.getTransTimestamp());
        return br;
    }

    public UnbindingRecord setUnbindRecord(ReceiveBindingInfo receivSgsInfo) {
        UnbindingRecord br = new UnbindingRecord();
        br.setCourierPhone(receivSgsInfo.getCourierPhone());
        br.setCustomerPhone(receivSgsInfo.getCustomerPhone());
        br.setMsgType(receivSgsInfo.getMsgType());
        br.setReservedTime(receivSgsInfo.getReservedTime());
        br.setExtendField1(receivSgsInfo.getExtendField1());
        br.setExtendField2(receivSgsInfo.getExtendField2());
        br.setSysCode(receivSgsInfo.getSysCode());
        br.setOriginTransId(receivSgsInfo.getTransId());
        br.setTransId(receivSgsInfo.getTransId());
        br.setTransTimestamp(receivSgsInfo.getTransTimestamp());
        return br;
    }


}
